#include "do_co2.h"
#include "w55mh32.h"
#include <stdint.h>

// 串口3相关全局变量定义
uint16_t g_co2_concentration = 0;            // CO2浓度值
volatile uint8_t g_uart3_rx_buffer[6];       // 接收缓冲区
volatile uint8_t g_uart3_rx_index = 0;       // 接收索引
volatile uint8_t g_uart3_data_ready = 0;     // 数据就绪标志
volatile uint16_t g_full_scale = 0;          // 满量程值
volatile uint8_t g_uart3_checksum_error = 0; // 校验错误标志
volatile uint8_t g_uart3_address_error = 0;  // 地址错误标志

// 串口3初始化
void co2_usart3_init(uint32_t baudrate) {
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  // 使能时钟 (根据您的MCU型号调整)
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,
                         ENABLE); // 假设USART3使用PB10(TX), PB11(RX)
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

  // 配置USART3 TX (PB10) 为复用推挽输出
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  // 配置USART3 RX (PB11) 为浮空输入
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  // USART参数配置
  USART_InitStructure.USART_BaudRate = baudrate;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl =
      USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART3, &USART_InitStructure);

  // 使能接收中断
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

  // 配置USART3中断
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 优先级低于串口2
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  // 使能串口
  USART_Cmd(USART3, ENABLE);
}

void usar_t3_irq_handler(void) {
  if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
    // 读取接收到的数据
    uint8_t received_byte = USART_ReceiveData(USART3);

    // 检查是否是新帧开始
    if (g_uart3_rx_index == 0 && received_byte != 0x2C) {
      // 不是预期的帧头，等待下一个字节
      return;
    }

    // 存储数据
    g_uart3_rx_buffer[g_uart3_rx_index] = received_byte;
    g_uart3_rx_index++;

    // 检查是否接收到完整帧
    if (g_uart3_rx_index >= 6) {
      g_uart3_rx_index = 0;   // 重置索引准备接收下一帧
      g_uart3_data_ready = 1; // 设置数据就绪标志
    }

    // 清除中断标志
    USART_ClearITPendingBit(USART3, USART_IT_RXNE);
  }
}

void co2_data_process_usart3(void) {
  // 1. 检查模块地址 (应为0x2C)
  if (g_uart3_rx_buffer[0] != 0x2C) {
    g_uart3_address_error = 1;
    return;
  }
  g_uart3_address_error = 0;

  // 2. 计算校验和
  uint8_t calculated_checksum = 0;
  for (int i = 0; i < 5; i++) {
    calculated_checksum += g_uart3_rx_buffer[i];
  }

  // 3. 获取接收到的校验位（第六字节）
  uint8_t received_checksum = g_uart3_rx_buffer[5];

  // 4. 校验检查
  if (calculated_checksum != received_checksum) {
    g_uart3_checksum_error = 1;
    return; // 校验失败，丢弃数据
  }
  g_uart3_checksum_error = 0;

  // 5. 计算CO2浓度值
  // CO2浓度 = (高位字节 << 8) | 低位字节
  g_co2_concentration = (g_uart3_rx_buffer[1] << 8) | g_uart3_rx_buffer[2];

  // 6. 计算满量程值（可选）
  g_full_scale = (g_uart3_rx_buffer[3] << 8) | g_uart3_rx_buffer[4];
}
